{"id":128,"date":"2017-05-23T10:02:33","date_gmt":"2017-05-23T09:02:33","guid":{"rendered":"http:\/\/marvinferber.net\/?p=128"},"modified":"2017-05-26T15:34:49","modified_gmt":"2017-05-26T14:34:49","slug":"using-sweethome3d-models-in-the-gazebo-simulator-part-1-create-and-export-the-scene","status":"publish","type":"post","link":"https:\/\/marvinferber.net\/?p=128","title":{"rendered":"Using Sweethome3D models in the Gazebo Simulator Part 1: Create and export the scene"},"content":{"rendered":"<p>Since I showed a nice simulation of <a href=\"http:\/\/www.turtlebot.com\/\">Turtlebot 2<\/a> in a home scene in <a href=\"http:\/\/gazebosim.org\/\">Gazebo<\/a> at the <a href=\"http:\/\/marvinferber.net\/?p=110\">MakerFaire Chemnitz<\/a>, I am going to share information on how you can do this on your own. At first, I have to mention that many open source software is involved here. In summary:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.sweethome3d.com\/\">Sweethome3D<\/a> (v. 4.3 and newer) modeling software and house designer<\/li>\n<li><a href=\"https:\/\/www.blender.org\/\">Blender 3D<\/a> 2.7 modeling software<\/li>\n<li><a href=\"https:\/\/www.python.org\/\">Python 2.7<\/a> for script-based model conversion<\/li>\n<\/ul>\n<p>Be aware that all descriptions below have been tested an <a href=\"http:\/\/releases.ubuntu.com\/14.04\/\">Ubuntu 14.04 LTS <\/a>and should also work on derived distros such as <a href=\"https:\/\/www.linuxmint.com\/release.php?id=26\">Linux Mint 17.3<\/a>, which I usually use.<\/p>\n<p>The actual creation of a an <a href=\"http:\/\/sdformat.org\/\">SDF<\/a> file as input for a Gazebo simulation is covered by a subsequent tutorial. The model we create here is necessary for the simulation of collisions and optical attributes of the scene. In this tutorial, we will create a model of a small flat in which the Turtlebot 2 can move around.<\/p>\n<h2>Creating a 3D scene in Sweethome3D for simulation<\/h2>\n<p>Once you have installed Sweethome3D (which is available from many Linux distro sources), there are a variety of <a href=\"http:\/\/www.sweethome3d.com\/gallery.jsp\">example scenes<\/a> to start from. Let&#8217;s choose <a href=\"http:\/\/www.sweethome3d.com\/examples\/SweetHome3DExample5.sh3d\">SweetHome3DExample5.sh3d<\/a> to work with. Just open this nice little flat in Sweethome3D. Unfortunately, this scene contains obstacles that can hardly be overcome by a Turtlebot 2: closed (and even half-open) doors! The reason why doors are a problem here is that the scene is static and doors will not move in the simulator. They stay closed. To change this, we would have to provide a physics model for the doors, too, which is far beyond the scope of this post. (Readers! Feel free to contribute here how doors can be made dynamic \ud83d\ude09 ) As a result, we should substitute all doors in the Sweethome3D scene by free passages of the same dimensions. The robot will appreciate this later when moving between rooms. As a second (optional) modification, I recommend to remove the ceiling from the Sweethome3D model. Having a ceiling will result in a non-transparent obstacle that makes it hard to look inside the flat from a birds position in the simulator.<\/p>\n<figure id=\"attachment_133\" aria-describedby=\"caption-attachment-133\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-133 size-full\" src=\"http:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/doors.png\" alt=\"\" width=\"800\" height=\"241\" srcset=\"https:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/doors.png 800w, https:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/doors-300x90.png 300w, https:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/doors-768x231.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-133\" class=\"wp-caption-text\">Sweethome3D scene with doors (rendering)<\/figcaption><\/figure>\n<figure id=\"attachment_134\" aria-describedby=\"caption-attachment-134\" style=\"width: 800px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-134 size-full\" src=\"http:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/nodoors.png\" alt=\"\" width=\"800\" height=\"241\" srcset=\"https:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/nodoors.png 800w, https:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/nodoors-300x90.png 300w, https:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/nodoors-768x231.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption id=\"caption-attachment-134\" class=\"wp-caption-text\">Sweethome3D scene with free passages (rendering)<\/figcaption><\/figure>\n<p>Finally, export the scene as .obj file from Sweethome3D using the menu &#8220;3D view&#8221;. Fortunately, all textures will also be exported. The number of exported files may be huge, depending on the complexity of the scene with respect to texture.<\/p>\n<p>I also want to mention explicitly that Sweethome3D can be extended extensively by custom textures for walls, floor and ceiling. Also, it is possible to import furniture either from self-made .obj files or from a variety of furniture libraries available on th Web. This makes Sweethome3D an excellent choice for creating semi-realistic scenes in a quick and effective way.<\/p>\n<h2>Convert .obj to .dae preserving textures using a Blender-based Python script<\/h2>\n<p>The .obj file that was exported from Sweethome3D cannot be used with Gazebo for simulation directly. It has to be converted to .dae format (<a href=\"https:\/\/www.khronos.org\/collada\/wiki\/Main_page\">COLLADA<\/a>). Although this is a task that many programs can perform, many programs also fail to process textures correctly or require a lot of GUI clicking for the conversion. I found a nice Blender-based Python script that does the trick on command line easily. Thanks to AngryLoki for the code snippet that converts in the reverse order (<a href=\"https:\/\/gist.github.com\/AngryLoki\/3800594\">dae2obj.py<\/a>). However, installing the necessary dependencies is a bit tricky here.<\/p>\n<ul>\n<li>Install Blender 2.7 from <a href=\"https:\/\/launchpad.net\/~irie\/+archive\/ubuntu\/blender\">IRIE Shinsuke PPA<\/a> to get the required scripting libraries<\/li>\n<li>Use a Python 2.7 installation<\/li>\n<\/ul>\n<p>The script below converts all .obj files an a directory <code class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">input_dir<\/code> and puts all output to a directory <code class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">output_dir<\/code>. Given that you named the file <code class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">obj2dae.py<\/code>, the script is invoked from a command line like this: <code class=\"EnlighterJSRAW\" data-enlighter-language=\"shell\">blender --background --python obj2dae.py -- input_dir output_dir<\/code><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\"># simple script to batch convert obj to collada preserving textures\r\n# run as:\r\n# blender --background --python obj2dae.py -- input_dir output_dir\r\n\r\nimport os\r\nimport sys\r\nimport glob\r\nimport bpy\r\n\r\nif len(sys.argv) != 9:\r\n    print(\"Must provide input and output path\")\r\nelse:\r\n    for infile in glob.glob(os.path.join(sys.argv[7], '*.obj')):\r\n        bpy.ops.object.select_all(action='SELECT')\r\n        bpy.ops.object.delete()\r\n        bpy.ops.import_scene.obj(filepath=infile)\r\n        outfilename = os.path.splitext(os.path.split(infile)[1])[0] + \".dae\"\r\n        bpy.ops.wm.collada_export(filepath=os.path.join(sys.argv[8], outfilename),include_uv_textures=True, include_material_textures=True)<\/pre>\n<p>Voil\u00e0, we just created a 3D model that can be used inside the Gazebo simulator. It will preserve texture. Please keep in mind that you can use any Sweethome3D model as input. Be creative!<\/p>\n<p>Happy Hacking \ud83d\ude09<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>Since I showed a nice simulation of Turtlebot 2 in a home scene in Gazebo at the MakerFaire Chemnitz, I am going to share information <a class=\"mh-excerpt-more\" href=\"https:\/\/marvinferber.net\/?p=128\" title=\"Using Sweethome3D models in the Gazebo Simulator Part 1: Create and export the scene\">[&#8230;]<\/a><\/p>\n<\/div>","protected":false},"author":1,"featured_media":146,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[6,7],"tags":[],"class_list":["post-128","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gazebo","category-sweethome3d"],"jetpack_featured_media_url":"https:\/\/marvinferber.net\/wp-content\/uploads\/2017\/05\/Screenshot-e1495623849502.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/marvinferber.net\/index.php?rest_route=\/wp\/v2\/posts\/128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/marvinferber.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/marvinferber.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/marvinferber.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/marvinferber.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=128"}],"version-history":[{"count":17,"href":"https:\/\/marvinferber.net\/index.php?rest_route=\/wp\/v2\/posts\/128\/revisions"}],"predecessor-version":[{"id":149,"href":"https:\/\/marvinferber.net\/index.php?rest_route=\/wp\/v2\/posts\/128\/revisions\/149"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/marvinferber.net\/index.php?rest_route=\/wp\/v2\/media\/146"}],"wp:attachment":[{"href":"https:\/\/marvinferber.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/marvinferber.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/marvinferber.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}