Home | Tutorials | Wiki | Issues
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

The reason why unit cubes show up, where one would expect the procedurally generated mesh to be, is because the mesh is produced in the server, and when it's added to the MeshManager in the server, that's where it's going to stay - in the server.

The client doesn't have access to an instance of the MeshManager singleton from the server, since it runs on a separate process.

The server, however, publishes a message with the SDF information. When the client receives this SDF message from the server, it then looks for a file called "Tree_1234" that is supposed to have the mesh information (more in particularly, in collada format), but it can't find it - since there is no file called "Tree_1234" and by default it generates a unit cube instead.

The simplest solution is to save off the mesh to a file first - as shown here:

gazebo::common::Mesh * treeMesh = procTreeFunction();
treeMesh->SetName("Tree_1234");
gazebo::common::MeshManager::Instance()->Export(treeMesh, "Tree_1234", std::string("dae"), false);

and then refer to this file in the SDF uri field as follows (and note the .dae extension):

modelStr << "<sdf version='" << SDF_VERSION << "'>"
  "<model name='" Tree_1234 "'>"
  "<pose>" << pose << "</pose>"
  "<link name='link'>"
    "<velocity_decay>"
      "<linear>0.01</linear>"
      "<angular>0.01</angular>"
    "</velocity_decay>"
    "<inertial><mass>" << _mass << "</mass>"
      "<inertia>"
      "<ixx>" << Ixx << "</ixx>"
      "<iyy>" << Iyy << "</iyy>"
      "<izz>" << Izz << "</izz>"
      "<ixy>" << 0.0 << "</ixy>"
      "<ixz>" << 0.0 << "</ixz>"
      "<iyz>" << 0.0 << "</iyz>"
      "</inertia>"
    "</inertial>"
    "<collision name='collision'>"
      "<geometry>"
        "<mesh>"
          "<uri>" Tree_1234.dae "</uri>"
        "</mesh>"
      "</geometry>"
    "</collision>"
    "<visual name='visual'>"
      "<geometry>"
        "<mesh>"
          "<uri>" Tree_1234.dae "</uri>"
        "</mesh>"
      "</geometry>"
        "<material>"
           "<ambient>"  << _materialAmbient[0]  << " " << _materialAmbient[1]  << " " << _materialAmbient[2]  << " " << _materialAmbient[3] <<"</ambient>"
           "<diffuse>"  << _materialDiffuse[0]  << " " << _materialDiffuse[1]  << " " << _materialDiffuse[2]  << " " << _materialDiffuse[3] <<"</diffuse>"
           "<specular>" << _materialSpecular[0] << " " << _materialSpecular[1] << " " << _materialSpecular[2] << " " << _materialSpecular[3] <<"</specular>"
          "<emissive>"  << _materialEmissive[0] << " " << _materialEmissive[1] << " " << _materialEmissive[2] << " " << _materialEmissive[3] <<"</emissive>"
        "</material>"
    "</visual>"
  "</link>"
"</model>"
"</sdf>";

This works just fine, but the downside is that it will produce tons of meshes, one for each tree. Maybe not a big issue for some, maybe a huge inconvenience for others.

For the latter, I would suggest a more advanced method (and a more elegant one in my opinion) where one would create a second plugin that runs on the client and which subscribes to a customized "mesh-messages" - a message that should include all the vertices, normals and uv-coordinates of a mesh - that the first plugin (i.e. the one that runs on the server) is going to publish.

The reason why unit cubes show up, where one would expect the procedurally generated mesh to be, is because the mesh is produced in the server, and when it's added to the MeshManager in the server, that's where it's going to stay - in the server.

The client doesn't have access to an instance of the MeshManager singleton from the server, since it runs on a separate process.

The server, however, publishes a message with the SDF information. When the client receives this SDF message from the server, it then looks for a file called "Tree_1234" that is supposed to have the mesh information (more in particularly, in collada format), but it can't find it - since there is no file called "Tree_1234" and by default it generates a unit cube instead.

The simplest solution is to save off the mesh to a file first - as shown here:

gazebo::common::Mesh * treeMesh = procTreeFunction();
treeMesh->SetName("Tree_1234");
gazebo::common::MeshManager::Instance()->Export(treeMesh, "Tree_1234", std::string("dae"), false);

and then refer to this file in the SDF uri field as follows (and note the .dae extension):

modelStr << "<sdf version='" << SDF_VERSION << "'>"
  "<model name='" Tree_1234 "'>"
  "<pose>" << pose << "</pose>"
  "<link name='link'>"
    "<velocity_decay>"
      "<linear>0.01</linear>"
      "<angular>0.01</angular>"
    "</velocity_decay>"
    "<inertial><mass>" << _mass << "</mass>"
      "<inertia>"
      "<ixx>" << Ixx << "</ixx>"
      "<iyy>" << Iyy << "</iyy>"
      "<izz>" << Izz << "</izz>"
      "<ixy>" << 0.0 << "</ixy>"
      "<ixz>" << 0.0 << "</ixz>"
      "<iyz>" << 0.0 << "</iyz>"
      "</inertia>"
    "</inertial>"
    "<collision name='collision'>"
      "<geometry>"
        "<mesh>"
          "<uri>" Tree_1234.dae "</uri>"
        "</mesh>"
      "</geometry>"
    "</collision>"
    "<visual name='visual'>"
      "<geometry>"
        "<mesh>"
          "<uri>" Tree_1234.dae "</uri>"
        "</mesh>"
      "</geometry>"
        "<material>"
           "<ambient>"  << _materialAmbient[0]  << " " << _materialAmbient[1]  << " " << _materialAmbient[2]  << " " << _materialAmbient[3] <<"</ambient>"
           "<diffuse>"  << _materialDiffuse[0]  << " " << _materialDiffuse[1]  << " " << _materialDiffuse[2]  << " " << _materialDiffuse[3] <<"</diffuse>"
           "<specular>" << _materialSpecular[0] << " " << _materialSpecular[1] << " " << _materialSpecular[2] << " " << _materialSpecular[3] <<"</specular>"
          "<emissive>"  << _materialEmissive[0] << " " << _materialEmissive[1] << " " << _materialEmissive[2] << " " << _materialEmissive[3] <<"</emissive>"
        "</material>"
    "</visual>"
  "</link>"
"</model>"
"</sdf>";

This works just fine, but the downside is that it will produce tons of meshes, one for each tree. Maybe not a big issue for some, maybe a huge inconvenience for others.

For the latter, I would suggest a more advanced method (and a more elegant one in my opinion) where one would create a second plugin that runs on the client and which subscribes to a customized "mesh-messages" - a message that should include all the vertices, normals and uv-coordinates of a mesh - that the first plugin (i.e. the one that runs on the server) is going to publish.

Here is a screen shot of procedurally generated trees that are loaded in Gazebo using the former method (saving off each mesh to a .dae file) - this is still a work in progress. Each tree is the location of an actual tree in the world that was recorded by placing markers in Google Earth and then parsing the KML file.

image description