ROS2 and Gazebo: Creating a 3d world


Download link:
Note: This archive should be added to archive.

Important! The code has a potential problem that is fixed in the next section and is not a show stopper for a Python programmers, but I think you should know about it.
DAE that was saved automatically for us by o3d library contains some odd problems. I might, at some point, write my own DAE saver function, but right now I am parsing the DAE I got from tri_mesh.export() function and edit it in code.
!!!Very important!!!
This approach is dangerous! Imagine that you install a newer version of o3d library and it saves DAE with different formating. It might break the functionality of this parser.
This was your fair warning. The current version of o3d I am using is 0.13.0
Note2: once again, fixed in the next release on

How to set your library to a fixed version. Here I am setting version of o3d, and not tri_mesh, as in the next section I got rid of tri_mesh library completely.

                $ pip freeze | grep open3d

The code for this section is located in an archive (see the download link above). It contains utilities that produce landscape meshes and some other files that will help you to run simulations in the "land with hills", not just on the flat surface.

As it doesn't introduce any extra ROS2 code, instead of building and running it you can build and run one of the earlier projects: the only difference will be that we point it (using command line parameters) to a different world file. I recommend using "simple" version of multi_bot_nav_02 (was introduced in earlier section). Also note that we use ROS2 Galactic.


Most libraries (like Nav2) at the moment work in a flat world, which is totally inacceptible if we want to create an agricultural robot, marsian explorer or simply a delivery bot with "do not drive to the ditch" feature. We need to be able to run in so-called 2.5D environment... and the question is, how do we build the world?

Well, we use 3d (2.d) mesh that presents the landscape.


Gazebo works with two 3d mesh formats, STL and DAE (Collada). In this section will provide a tool to handle both. Keep in mind however, that Gazebo uses OGRE format for materials. What that means is that you (probably) can not load 3d mesh with texture directly.

Once again: DAE supports embedded textures, Gazebo doesn't. It is not a problem, just something to keep in mind. STL doesn't have texture in any case, but DAE does... and it only works through the .material files (again, it is possible that there is some weird combination of flags that I wasn't able to find, it is, after all, Gazebo).

What it means for us? Not a lot: in addition to a DAE file and texture, we need a material file to link them together (which is trivial), and we need to (I can not believe I am saying that!) comment out the reference to texture image in the DAE file. This way Gazebo picks the texture provided in the .material file. And if we do not comment it out - texture refered to in "material" file has priority... which works too. Except, we need a material file no mater if direct reference to texture is present in DAE or not. Hm? No comments.

I just mentioned that I will provide a way to get STL files. Well, they will have no texture. Because you see, texture should be "mapped", so Gazebo knows which point of a texture image corresponds to which point of a mesh. I provide mapping for each vertex of a mesh, but if you want, you can experiment, making it less demanding in terms of speed.

The mapping is stored inside the DAE file, but not inside the STL file. So, watch my hands: we store mapping in DAE, we comment out the image in DAE, and we provide image in .material file. "For your convenience" (sarcasm). Or we work with STL and have no texture, which is acceptable in some cases, too.

The script saves both STL and DAE files; do not forget to comment out the reference to a texture image in DAE file, if you want to use it in a Gazebo world. Technically, you can leave it uncommented, but then when you want to change something (and I felt in this trap myself), you will most likely forget about material file, because you see a direct link to a texture... and yet your simulation uses another texture (one from "material" file). Something to keep in mind.

(C), all rights reserved

Please read the disclaimer