Building indoor worlds for a mobile robot by hand is slow. Placing every wall, door and piece of furniture in SDF, or clicking it together in the Gazebo building editor, takes hours and rarely looks like a real home. SweetHome 3D solves the design half of that problem. It is a free interior design tool where you draw a floor plan, drop in furniture and get a usable 3D model in minutes. This post walks through getting that model into Gazebo so you can drive a robot around it.
I reach for this when I need indoor navigation and SLAM scenes, where a believable room layout matters more than physical accuracy.
1. Design the home in SweetHome 3D
Draw the floor plan, then add walls, doors, windows and furniture. Keep real world dimensions in mind, since we want the export to line up with meters later. Once the layout looks right, switch to the 3D view.
2. Export to OBJ
From the 3D view menu, choose Export to OBJ format. SweetHome 3D writes three things: the geometry (.obj), the materials (.mtl) and a set of texture images. Keep all of them in one folder, because the .mtl and textures are referenced by relative path and will break if they get separated.
3. Fix scale and orientation in Blender
The raw OBJ is not ready for Gazebo yet. Two things usually need fixing:
- Units. Gazebo works in meters. Check the size of the imported model and apply a scale factor if the house comes in too large or too small.
- Axes. SweetHome 3D exports with Y pointing up, while Gazebo and ROS use Z up.
Import the OBJ into Blender using the Y up option, measure a known wall to confirm the scale, then export to Collada (.dae). Collada keeps the material and texture references, which makes the next step easier. Keep the floor at Z equal to zero so the model sits on the ground plane.
4. Wrap it as a Gazebo model
Gazebo loads a model from a folder that holds a model.config and a model.sdf, with the mesh and textures in a meshes subfolder.
model.config:
<?xml version="1.0"?>
<model>
<name>my_home</name>
<version>1.0</version>
<sdf version="1.6">model.sdf</sdf>
<description>Indoor home environment from SweetHome 3D</description>
</model>model.sdf:
<?xml version="1.0"?>
<sdf version="1.6">
<model name="my_home">
<static>true</static>
<link name="body">
<visual name="visual">
<geometry>
<mesh><uri>model://my_home/meshes/home.dae</uri></mesh>
</geometry>
</visual>
<collision name="collision">
<geometry>
<mesh><uri>model://my_home/meshes/home.dae</uri></mesh>
</geometry>
</collision>
</link>
</model>
</sdf>A building does not move, so mark it static true. That skips physics on the mesh and keeps the simulation light.
5. Make Gazebo find it
Put the model folder where Gazebo looks for models. On Gazebo Classic that is a path in GAZEBO_MODEL_PATH, or you can drop the folder into ~/.gazebo/models. On new Gazebo (Sim / Harmonic) it is GZ_SIM_RESOURCE_PATH. Then insert the model into your world, either from the Insert tab in the GUI or by adding it to your .world file:
<include>
<uri>model://my_home</uri>
</include>6. Collision and performance
Using the full detailed mesh for collision is the quick option, but a house has a lot of triangles and the physics engine will feel every one of them. For anything larger than a single room, replace the collision geometry with something cheaper. Two approaches work well:
- Simplify the collision mesh in Blender with a decimate modifier before exporting.
- Model the walls as a set of box collisions and keep the detailed mesh for visuals only.
For 2D navigation the robot mostly cares about walls and large furniture, so box collisions for the walls are usually enough.
Wrapping up
With the model in place you can drop a differential drive robot into the world, run your mapping stack and watch it build a map of a room that actually looks like a room. It is a fast way to get varied, realistic indoor scenes without hand building every wall in SDF.