{"componentChunkName":"component---src-templates-post-post-jsx","path":"/blog/sweethome3d-gazebo","result":{"data":{"markdownRemark":{"html":"<p>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.</p>\n<p>I reach for this when I need indoor navigation and SLAM scenes, where a believable room layout matters more than physical accuracy.</p>\n<h3>1. Design the home in SweetHome 3D</h3>\n<p>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.</p>\n<h3>2. Export to OBJ</h3>\n<p>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.</p>\n<h3>3. Fix scale and orientation in Blender</h3>\n<p>The raw OBJ is not ready for Gazebo yet. Two things usually need fixing:</p>\n<ul>\n<li>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.</li>\n<li>Axes. SweetHome 3D exports with Y pointing up, while Gazebo and ROS use Z up.</li>\n</ul>\n<p>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.</p>\n<h3>4. Wrap it as a Gazebo model</h3>\n<p>Gazebo loads a model from a folder that holds a <code class=\"language-text\">model.config</code> and a <code class=\"language-text\">model.sdf</code>, with the mesh and textures in a <code class=\"language-text\">meshes</code> subfolder.</p>\n<p><code class=\"language-text\">model.config</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token prolog\">&lt;?xml version=\"1.0\"?></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>model</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>name</span><span class=\"token punctuation\">></span></span>my_home<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>name</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>version</span><span class=\"token punctuation\">></span></span>1.0<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>version</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>sdf</span> <span class=\"token attr-name\">version</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>1.6<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>model.sdf<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>sdf</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>description</span><span class=\"token punctuation\">></span></span>Indoor home environment from SweetHome 3D<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>description</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>model</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p><code class=\"language-text\">model.sdf</code>:</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token prolog\">&lt;?xml version=\"1.0\"?></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>sdf</span> <span class=\"token attr-name\">version</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>1.6<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>model</span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>my_home<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>static</span><span class=\"token punctuation\">></span></span>true<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>static</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>link</span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>body<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>visual</span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>visual<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>geometry</span><span class=\"token punctuation\">></span></span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>mesh</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>uri</span><span class=\"token punctuation\">></span></span>model://my_home/meshes/home.dae<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>uri</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>mesh</span><span class=\"token punctuation\">></span></span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>geometry</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>visual</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>collision</span> <span class=\"token attr-name\">name</span><span class=\"token attr-value\"><span class=\"token punctuation\">=</span><span class=\"token punctuation\">\"</span>collision<span class=\"token punctuation\">\"</span></span><span class=\"token punctuation\">></span></span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>geometry</span><span class=\"token punctuation\">></span></span>\n          <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>mesh</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>uri</span><span class=\"token punctuation\">></span></span>model://my_home/meshes/home.dae<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>uri</span><span class=\"token punctuation\">></span></span><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>mesh</span><span class=\"token punctuation\">></span></span>\n        <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>geometry</span><span class=\"token punctuation\">></span></span>\n      <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>collision</span><span class=\"token punctuation\">></span></span>\n    <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>link</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>model</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>sdf</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<p>A building does not move, so mark it <code class=\"language-text\">static</code> true. That skips physics on the mesh and keeps the simulation light.</p>\n<h3>5. Make Gazebo find it</h3>\n<p>Put the model folder where Gazebo looks for models. On Gazebo Classic that is a path in <code class=\"language-text\">GAZEBO_MODEL_PATH</code>, or you can drop the folder into <code class=\"language-text\">~/.gazebo/models</code>. On new Gazebo (Sim / Harmonic) it is <code class=\"language-text\">GZ_SIM_RESOURCE_PATH</code>. Then insert the model into your world, either from the Insert tab in the GUI or by adding it to your <code class=\"language-text\">.world</code> file:</p>\n<div class=\"gatsby-highlight\" data-language=\"xml\"><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>include</span><span class=\"token punctuation\">></span></span>\n  <span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>uri</span><span class=\"token punctuation\">></span></span>model://my_home<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>uri</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>include</span><span class=\"token punctuation\">></span></span></code></pre></div>\n<h3>6. Collision and performance</h3>\n<p>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:</p>\n<ul>\n<li>Simplify the collision mesh in Blender with a decimate modifier before exporting.</li>\n<li>Model the walls as a set of box collisions and keep the detailed mesh for visuals only.</li>\n</ul>\n<p>For 2D navigation the robot mostly cares about walls and large furniture, so box collisions for the walls are usually enough.</p>\n<h3>Wrapping up</h3>\n<p>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.</p>","timeToRead":3,"frontmatter":{"title":"Importing a SweetHome 3D Home into Gazebo","date":"04 Jul 2026","tags":["sim","ros"],"path":"blog/sweethome3d-gazebo","excerpt":"A quick pipeline for turning a SweetHome 3D floor plan into a Gazebo world you can drive a robot around.","cover":{"childImageSharp":{"fluid":{"tracedSVG":"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='400'%20height='233'%20viewBox='0%200%20400%20233'%20preserveAspectRatio='none'%3e%3cpath%20d='M0%20117v116h401V0H0v117m27-29c-3%202-2%206%202%208%205%203%205%204%200%204-5-1-6%202-1%203%209%202%2013-8%204-10-4%200-3-3%201-2%203%200%203%200%203-2-1-2-7-3-9-1m73%207c0%207%200%208%202%208s2-1%202-3c0-3%200-3%203-3%202%200%203%200%202%203%200%203%200%203%202%203h3v-8c0-7-1-7-2-7-2%200-2%200-2%202%200%204-6%204-6%200l-2-3c-2%200-2%201-2%208m76-7c0%202%201%202%204%202%203%201%204%203%201%203-3%201-4%203-1%203%204%201%203%205-1%204-4%200-4%202-1%203%206%202%2011-3%208-7v-2c2-2%201-5-1-6h-9m15%207v8h5c13%200%2013-14%200-16h-5v8m60-7c-7%204-4%2015%204%2015%206%200%207-1%207-5s0-4-3-4c-2%200-3%201-3%202l1%201%201%202-3%201c-2%200-3-1-3-4%200-5%202-7%207-5l3-1c0-3-6-4-11-2m56%207v8h7c2%202%205-1%206-4%201-5-2-8-6-8-3%201-3%201-3-2l-2-2c-2%200-2%201-2%208M40%2093c0%209%206%2014%208%206l1-3v3l3%204c3%200%207-11%204-12-1%200-3%202-3%205s-2%202-2-2c-1-4-4-4-5%200l-1%203-1-3c-1-3-4-4-4-1m21%200c-5%205%201%2012%208%2010%203-1%203-3-2-3l-4-1%204-1%205-1c0-3-4-6-6-6l-5%202m15%200c-6%204-1%2012%207%2010%204-1%204-3-1-3l-4-1%204-1c5%200%205%200%204-3-2-4-6-5-10-2m42%200c-3%203-3%206%201%209%204%204%2010%201%2010-5%200-5-7-8-11-4m14%204c0%205%200%206%202%206s2-1%202-4c1-6%203-6%203-1%200%204%200%205%202%205s2-1%202-4%201-4%202-4%202%201%202%204%200%204%202%204%202-1%202-3c0-7-3-10-7-8h-2l-6-1h-4v6m23-4c-5%205%201%2012%208%2010%203-1%203-3-2-3l-4-1%204-1%205-1c0-3-4-6-6-6l-5%202m72%200c-3%203-3%206%201%209%204%204%2010%201%2010-5%200-5-7-8-11-4m39%200l4%201%203%201-3%201c-3%200-5%202-5%204s4%204%205%203h4c3%200%203%200%203-4%200-6-2-8-7-8-3%200-4%200-4%202m28%200c-5%205%200%2012%207%2010%204-1%204-3-1-3l-4-1%204-1c3%200%204%200%204-2%200-4-7-7-10-3m30%200c-4%204-2%2010%204%2010%204%200%206-2%206-5%200-6-7-9-10-5'%20fill='%23d3d3d3'%20fill-rule='evenodd'/%3e%3c/svg%3e","aspectRatio":1.7123287671232876,"src":"/static/48dbfb3d62f92361a143593300ca011c/31987/preview.png","srcSet":"/static/48dbfb3d62f92361a143593300ca011c/e1953/preview.png 250w,\n/static/48dbfb3d62f92361a143593300ca011c/46604/preview.png 500w,\n/static/48dbfb3d62f92361a143593300ca011c/31987/preview.png 1000w,\n/static/48dbfb3d62f92361a143593300ca011c/f3583/preview.png 1200w","sizes":"(max-width: 1000px) 100vw, 1000px"}}}}},"allMarkdownRemark":{"edges":[{"node":{"frontmatter":{"path":"blog/sim2real-quadcopter","title":"Synchronized Flight - Sim2Real for a Quadcopter","tags":["sim","ros"],"excerpt":"Building a quadcopter Flight Dynamics Model in Gazebo and matching it to real hardware.","cover":{"childImageSharp":{"fluid":{"tracedSVG":"data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='400'%20height='233'%20viewBox='0%200%20400%20233'%20preserveAspectRatio='none'%3e%3cpath%20d='M0%20117v116h401V0H0v117m29-28c-6%203-5%2010%203%2012l4%202c0%202%200%202-5%202-5-1-6-1-6%201%200%203%2011%204%2014%201%204-4%202-9-5-11-5-1-5-4%201-3%204%200%205%200%205-2l-1-2-5-1-5%201m57%200c-1%200-3%201-3%203s0%202%203%201c7-3%208%202%202%208-7%206-7%208%203%208%206%200%207%200%207-2s-1-2-4-2h-4l4-4c4-5%205-7%202-10-2-2-6-3-10-2m74%2010v10h5V88h-5v11m-58%200l1%2010h2c3%200%203%200%203-4%200-6%202-5%205%201%202%202%203%203%205%203%203%200%203%200%200-6-2-3-3-4-1-5%201-2%201-5-1-7-1-2-3-2-8-2h-6v10m-40-5h-7v7c0%207%200%208%202%208%201%200%202-1%202-5%201-9%205-9%205%200%200%205%200%205%203%205%202%200%202%200%202-5s2-8%204-7l1%207c0%205%200%205%203%205%202%200%202%200%202-6%200-8-4-12-9-9-1%202-2%202-3%200h-5m65%200c-5%202-6%209-2%2013%203%203%2012%203%2013%200%200-2%200-2-4-1l-6-1c-1-2-1-2%204-2%206%200%206%200%206-3%200-5-6-8-11-6m17%200c-4%201-3%204%202%203l4%201c1%201%200%201-2%201-4%200-8%203-8%205%200%204%207%207%2010%204h1l3%201c2%200%202%200%202-5%200-8-4-12-12-10'%20fill='%23d3d3d3'%20fill-rule='evenodd'/%3e%3c/svg%3e","aspectRatio":1.7045454545454546,"src":"/static/cbbc4c63c6c73005feafab986c5a65a9/2a4de/preview.png","srcSet":"/static/cbbc4c63c6c73005feafab986c5a65a9/6d161/preview.png 150w,\n/static/cbbc4c63c6c73005feafab986c5a65a9/630fb/preview.png 300w,\n/static/cbbc4c63c6c73005feafab986c5a65a9/2a4de/preview.png 600w,\n/static/cbbc4c63c6c73005feafab986c5a65a9/db955/preview.png 900w,\n/static/cbbc4c63c6c73005feafab986c5a65a9/f3583/preview.png 1200w","sizes":"(max-width: 600px) 100vw, 600px"}}}}}}]}},"pageContext":{"postPath":"blog/sweethome3d-gazebo","translations":[{"hreflang":"en","path":"/blog/sweethome3d-gazebo"}]}}}