From ea48ec448784f782bde6fb18b6215e82319266b7 Mon Sep 17 00:00:00 2001
From: Valenza Florian <fvalenza@laas.fr>
Date: Thu, 3 Mar 2016 14:09:58 +0100
Subject: [PATCH] [C++][Python][Parser Geom] Parse automatically the
 ROS_PACKAGE_PATH environment variable if not clue is given by the user to
 where to search for meshes. Change the meshRootDir argument to a vector of
 strings (package directories). Updated Python consequently

---
 CMakeLists.txt                               |  1 +
 benchmark/timings-geometry.cpp               | 10 ++-
 src/multibody/parser/from-collada-to-fcl.hpp | 31 +++++++-
 src/multibody/parser/urdf-with-geometry.hpp  | 63 ++++++++++------
 src/multibody/parser/urdf-with-geometry.hxx  | 79 +++++++++++---------
 src/python/parsers.hpp                       | 24 +++---
 unittest/geom.cpp                            | 49 +++++++-----
 7 files changed, 163 insertions(+), 94 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9393ca70c..b8d17d8af 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -86,6 +86,7 @@ SET(${PROJECT_NAME}_MATH_HEADERS
 SET(${PROJECT_NAME}_TOOLS_HEADERS
   tools/timer.hpp
   tools/string-generator.hpp
+  tools/file-explorer.hpp
   )
 
 SET(${PROJECT_NAME}_SPATIAL_HEADERS
diff --git a/benchmark/timings-geometry.cpp b/benchmark/timings-geometry.cpp
index 6d69bd232..7ee7b2939 100644
--- a/benchmark/timings-geometry.cpp
+++ b/benchmark/timings-geometry.cpp
@@ -69,11 +69,15 @@ int main()
 
 
   std::string romeo_filename = PINOCCHIO_SOURCE_DIR"/models/romeo.urdf";
+  std::vector < std::string > package_dirs;
   std::string romeo_meshDir  = PINOCCHIO_SOURCE_DIR"/models/";
-  Model model = se3::urdf::buildModel(romeo_filename, se3::JointModelFreeFlyer());
-  GeometryModel geom_model = se3::urdf::buildGeom(model, romeo_filename, romeo_meshDir);
+  package_dirs.push_back(romeo_meshDir);
+
+  se3::Model model = se3::urdf::buildModel(romeo_filename, se3::JointModelFreeFlyer());
+  se3::GeometryModel geom_model = se3::urdf::buildGeom(romeo_model, romeo_filename, package_dirs,  true);
+   
   Data data(model);
-  GeometryData geom_data (data, geom_model);
+  GeometryData geom_data(data, geom_model);
   geom_data.initializeListOfCollisionPairs();
 
 
diff --git a/src/multibody/parser/from-collada-to-fcl.hpp b/src/multibody/parser/from-collada-to-fcl.hpp
index 9106e0556..dd1b419be 100644
--- a/src/multibody/parser/from-collada-to-fcl.hpp
+++ b/src/multibody/parser/from-collada-to-fcl.hpp
@@ -35,6 +35,8 @@
 #include <hpp/fcl/BV/OBBRSS.h>
 #include <hpp/fcl/BVH/BVH_model.h>
 
+#include "pinocchio/tools/file-explorer.hpp"
+
 #include <exception>
 
 namespace se3
@@ -196,13 +198,36 @@ namespace se3
   
   
   /**
-   * @brief      Transform a cURL readable path (package://..) to an absolute path for urdf collision path
+   * @brief      Transform a package://.. mesh path to an absolute path, searching for a valid file 
+   *             in a list of package directories
    *
-   * @param[in]      urdf_mesh_path  The path given in the urdf file (package://..)
-   * @param[in]  meshRootDir     Root path to the directory where meshes are located
+   * @param[in]  urdf_mesh_path  The path given in the urdf file
+   * @param[in]  package_dirs    A list of packages directories where to search for meshes
    *
    * @return     The absolute path to the mesh file
    */
+   inline std::string fromURDFMeshPathToAbsolutePathPack(const std::string & urdf_mesh_path,
+                                                         const std::vector<std::string> & package_dirs)
+   {
+    // if exists p1/mesh, absolutePath = p1/mesh,
+    // else if exists p2/mesh, absolutePath = p2/mesh
+    // else return an empty string that will provoke an error in loadPolyhedronFromResource()
+    namespace bf = boost::filesystem;
+
+    std::string absolutePath;
+    // concatenate package_path with mesh filename
+    for (int i = 0; i < package_dirs.size(); ++i)
+    {
+      if ( bf::exists( bf::path(package_dirs[i] +  urdf_mesh_path.substr(9, urdf_mesh_path.size()))))
+      {
+          absolutePath = std::string( package_dirs[i] + urdf_mesh_path.substr(9, urdf_mesh_path.size())
+                                       );
+        break;
+      }
+    }
+    return absolutePath;
+   }
+
   inline std::string fromURDFMeshPathToAbsolutePath(const std::string & urdf_mesh_path,
                                                     const std::string & meshRootDir)
   {
diff --git a/src/multibody/parser/urdf-with-geometry.hpp b/src/multibody/parser/urdf-with-geometry.hpp
index 32d420bd0..6d9c1bb82 100644
--- a/src/multibody/parser/urdf-with-geometry.hpp
+++ b/src/multibody/parser/urdf-with-geometry.hpp
@@ -35,47 +35,62 @@ namespace se3
 
 
     /**
-     * @brief      Get a CollisionObject from an urdf link, reading the
-     *             corresponding mesh
+     * @brief      Get a CollisionObject from an urdf link, searching
+     *             for it in specified package directories
      *
-     * @param[in]  link         The input urdf link
-     * @param[in]  meshRootDir  Root path to the directory where meshes are located
+     * @param[in]  link          The input urdf link
+     * @param[in]  package_dirs  A vector containing the different directories where to search for packages
      *
      * @return     The mesh converted as a fcl::CollisionObject
      */
-    inline fcl::CollisionObject retrieveCollisionGeometry (const ::urdf::LinkConstPtr & link,
-                                                           const std::string & meshRootDir);
+    inline fcl::CollisionObject retrieveCollisionGeometry (const ::urdf::LinkConstPtr & link, const std::vector < std::string > & package_dirs);
 
     
     /**
      * @brief      Recursive procedure for reading the URDF tree, looking for geometries
      *             This function fill the geometric model whith geometry objects retrieved from the URDF tree
-     *
-     * @param[in]  link         The current URDF link
-     * @param      model        The model to which is the Geometry Model associated
-     * @param      model_geom   The Geometry Model where the Collision Objects must be added
-     * @param[in]  meshRootDir  Root path to the directory where meshes are located
+     * 
+     * @param[in]  link            The current URDF link
+     * @param      model           The model to which is the GeometryModel associated
+     * @param      model_geom      The GeometryModel where the Collision Objects must be added
+     * @param[in]  package_dirs    A vector containing the different directories where to search for packages
+     * @param[in]  rootJointAdded  If a root joint was added at the begining of the urdf kinematic chain by user when constructing the Model
      */
-    inline void parseTreeForGeom(::urdf::LinkConstPtr link,
-                                 const Model & model,
-                                 GeometryModel & model_geom,
-                                 const std::string & meshRootDir,
-                                 const bool rootJointAdded) throw (std::invalid_argument);
+    inline void parseTreeForGeom( ::urdf::LinkConstPtr link,
+                                const Model & model,
+                                GeometryModel & model_geom,
+                                const std::vector<std::string> & package_dirs,
+                                const bool rootJointAdded) throw (std::invalid_argument);
+
 
 
+    /**
+     * @brief      Build The GeometryModel from a URDF file 
+     *
+     * @param      model         The model of the robot, built with urdf::buildModel
+     * @param[in]  filename      The URDF complete (absolute) file path
+     * @param[in]  package_dirs  A vector containing the different directories where to search for packages
+     * @param[in]  root_joint    If we added a root joint to the Model in addition to the urdf kinematic chain
+     *
+     * @return     The GeometryModel associated to the urdf file and the Model given
+     */
+    inline GeometryModel buildGeom(const Model & model,
+                                  const std::string & filename,
+                                  const std::vector<std::string> & package_dirs,
+                                  const bool root_joint = false );
 
     /**
-     * @brief      Build the GeometryModel from a URDF file.
+     * @brief      Build The GeometryModel from a URDF file 
      *
-     * @param[in]  model     The model of the robot, built with urdf::buildModel.
-     * @param[in]  filename     The complete path to the URDF model.
-     * @param[in]  meshRootDir  Root path pointing to the directory where meshes are located.
+     * @param      model         The model of the robot, built with urdf::buildModel
+     * @param[in]  filename      The URDF complete (absolute) file path
+     * @param[in]  root_joint    If we added a root joint to the Model in addition to the urdf kinematic chain
      *
-     * @return     The geometric model.
+     * @return     The GeometryModel associated to the urdf file and the Model given
      */
-    GeometryModel buildGeom(const Model & model,
-                            const std::string & filename,
-                            const std::string & meshRootDir);
+    inline GeometryModel buildGeom(const Model & model,
+                                  const std::string & filename,
+                                  const bool root_joint = false );
 
   } // namespace urdf
   
diff --git a/src/multibody/parser/urdf-with-geometry.hxx b/src/multibody/parser/urdf-with-geometry.hxx
index 319241218..2404310dd 100644
--- a/src/multibody/parser/urdf-with-geometry.hxx
+++ b/src/multibody/parser/urdf-with-geometry.hxx
@@ -31,8 +31,7 @@ namespace se3
   namespace urdf
   {
     
-    inline fcl::CollisionObject retrieveCollisionGeometry (const ::urdf::LinkConstPtr & link,
-                                                           const std::string & meshRootDir)
+    inline fcl::CollisionObject retrieveCollisionGeometry (const ::urdf::LinkConstPtr & link, const std::vector < std::string > & package_dirs)
     {
       boost::shared_ptr < ::urdf::Collision> collision = link->collision;
       boost::shared_ptr < fcl::CollisionGeometry > geometry;
@@ -43,7 +42,7 @@ namespace se3
         boost::shared_ptr < ::urdf::Mesh> collisionGeometry = boost::dynamic_pointer_cast< ::urdf::Mesh> (collision->geometry);
         std::string collisionFilename = collisionGeometry->filename;
 
-        std::string full_path = fromURDFMeshPathToAbsolutePath(collisionFilename, meshRootDir);
+        std::string full_path = fromURDFMeshPathToAbsolutePathPack(collisionFilename, package_dirs);
 
         ::urdf::Vector3 scale = collisionGeometry->scale;
 
@@ -101,31 +100,38 @@ namespace se3
     inline void parseTreeForGeom(::urdf::LinkConstPtr link,
                                  const Model & model,
                                  GeometryModel & geom_model,
-                                 const std::string & meshRootDir,
+                                 const std::vector<std::string> & package_dirs,
                                  const bool rootJointAdded) throw (std::invalid_argument)
     {
 
       // start with first link that is not empty
-      if(link->collision)
+      if(link->inertial)
       {
         ::urdf::JointConstPtr joint = link->parent_joint;
 
-        if (joint == NULL && rootJointAdded)
+        if (joint == NULL && rootJointAdded )
         {
-            fcl::CollisionObject collision_object = retrieveCollisionGeometry(link, meshRootDir);
-            const SE3 geomPlacement = convertFromUrdf(link->collision->origin);
-            const std::string & collision_object_name = link->name ;
-            geom_model.addGeomObject(model.getJointId("root_joint"), collision_object, geomPlacement, collision_object_name);
           
+          if (link->collision)
+          {
+            fcl::CollisionObject collision_object = retrieveCollisionGeometry(link, package_dirs);
+            SE3 geomPlacement = convertFromUrdf(link->collision->origin);
+            std::string collision_object_name = link->name ;
+            geom_model.addGeomObject(model.getJointId("root_joint"), collision_object, geomPlacement, collision_object_name);
+          }
         }
-        else if(joint!=NULL)
+
+        if(joint!=NULL)
         {
           assert(link->getParent()!=NULL);
 
-          fcl::CollisionObject collision_object = retrieveCollisionGeometry(link, meshRootDir);
-          const SE3 geomPlacement = convertFromUrdf(link->collision->origin);
-          const std::string & collision_object_name = link->name ;
-          geom_model.addGeomObject(model.getJointId(joint->name), collision_object, geomPlacement, collision_object_name);
+          if (link->collision)
+          {
+            fcl::CollisionObject collision_object = retrieveCollisionGeometry(link, package_dirs);
+            SE3 geomPlacement = convertFromUrdf(link->collision->origin);
+            std::string collision_object_name = link->name ;
+            geom_model.addGeomObject(model.getJointId(joint->name), collision_object, geomPlacement, collision_object_name);
+          }      
         }
         else if (link->getParent() != NULL)
         {
@@ -133,34 +139,37 @@ namespace se3
           throw std::invalid_argument(exception_message);
         }
 
-      } // if(link->inertial)
+      }
       
       BOOST_FOREACH(::urdf::LinkConstPtr child,link->child_links)
       {
-        parseTreeForGeom(child, model, geom_model, meshRootDir, rootJointAdded);
+        parseTreeForGeom(child, model, geom_model, package_dirs, rootJointAdded);
       }
+
     }
 
-    GeometryModel buildGeom(const Model & model,
-                            const std::string & filename,
-                            const std::string & meshRootDir)
+
+    inline GeometryModel buildGeom(const Model & model,
+                                  const std::string & filename,
+                                  const std::vector<std::string> & package_dirs,
+                                  const bool root_joint)
     {
+      GeometryModel model_geom(model);
+
       ::urdf::ModelInterfacePtr urdfTree = ::urdf::parseURDFFile (filename);
-      ::urdf::LinkConstPtr root_link = urdfTree->getRoot();
-      if (!root_link->inertial) // if the first body is just a base_link, i.e. with no inertial info
-      {
-        ::urdf::LinkPtr child_link = root_link->child_links[0];
-        
-        // Change the name of the parent joint
-        child_link->parent_joint->name = "root_joint";
-      }
-      
-      // Read geometries
-      GeometryModel geom_model (model);
-      parseTreeForGeom(urdfTree->getRoot(), model, geom_model, meshRootDir, true);
-      
-      // Return a pair containing the kinematic tree and the geometries
-      return geom_model;
+      parseTreeForGeom(urdfTree->getRoot(), model, model_geom, package_dirs, root_joint);
+      return model_geom;
+    }
+
+    inline GeometryModel buildGeom(const Model & model,
+                                  const std::string & filename,
+                                  const bool root_joint)
+    {
+      GeometryModel model_geom(model);
+
+      ::urdf::ModelInterfacePtr urdfTree = ::urdf::parseURDFFile (filename);
+      parseTreeForGeom(urdfTree->getRoot(), model, model_geom, getRosPackagePaths(), root_joint);
+      return model_geom;
     }
 
   } // namespace urdf
diff --git a/src/python/parsers.hpp b/src/python/parsers.hpp
index 76ac059db..2227dd608 100644
--- a/src/python/parsers.hpp
+++ b/src/python/parsers.hpp
@@ -88,19 +88,19 @@ namespace se3
       struct build_model_and_geom_visitor : public boost::static_visitor<std::pair<ModelHandler, GeometryModelHandler> >
       {
         const std::string& _filenameUrdf;
-        const std::string& _filenameMeshRootDir;
+        const std::vector<std::string> & _package_dirs;
 
         build_model_and_geom_visitor(const std::string & filenameUrdf,
-                                     const std::string & filenameMeshRootDir)
+                                     const std::vector<std::string> & package_dirs)
           : _filenameUrdf(filenameUrdf)
-          , _filenameMeshRootDir(filenameMeshRootDir)
+          , _package_dirs(package_dirs)
         {}
 
         template <typename JointModel>
         ModelGeometryHandlerPair_t operator() (const JointModel & root_joint) const
         {
           Model * model = new Model(se3::urdf::buildModel(_filenameUrdf, root_joint));
-          GeometryModel * geometry_model = new GeometryModel (se3::urdf::buildGeom(*model, _filenameUrdf, _filenameMeshRootDir));
+          GeometryModel * geometry_model = new GeometryModel (se3::urdf::buildGeom(*model, _filenameUrdf, _package_dirs));
           
           return std::pair<ModelHandler, GeometryModelHandler> (ModelHandler(model, true),
                                                                 GeometryModelHandler(geometry_model, true)
@@ -110,20 +110,20 @@ namespace se3
 
       static ModelGeometryHandlerPair_t
       buildModelAndGeomFromUrdf(const std::string & filename,
-                                const std::string & mesh_dir,
+                                const std::vector<std::string> & package_dirs,
                                 bp::object & root_joint_object
                                 )
       {
         JointModelVariant root_joint = bp::extract<JointModelVariant> (root_joint_object);
-        return boost::apply_visitor(build_model_and_geom_visitor(filename, mesh_dir), root_joint);
+        return boost::apply_visitor(build_model_and_geom_visitor(filename, package_dirs), root_joint);
       }
 
       static ModelGeometryHandlerPair_t
       buildModelAndGeomFromUrdf(const std::string & filename,
-                                const std::string & mesh_dir)
+                                const std::vector<std::string> & package_dirs)
       {
         Model * model = new Model(se3::urdf::buildModel(filename));
-        GeometryModel * geometry_model = new GeometryModel(se3::urdf::buildGeom(*model, filename, mesh_dir));
+        GeometryModel * geometry_model = new GeometryModel(se3::urdf::buildGeom(*model, filename, package_dirs));
         
         return ModelGeometryHandlerPair_t (ModelHandler(model, true),
                                            GeometryModelHandler(geometry_model, true)
@@ -173,15 +173,15 @@ namespace se3
       bp::to_python_converter<std::pair<ModelHandler, GeometryModelHandler>, PairToTupleConverter<ModelHandler, GeometryModelHandler> >();
       
       bp::def("buildModelAndGeomFromUrdf",
-              static_cast <ModelGeometryHandlerPair_t (*) (const std::string &, const std::string &, bp::object &)> (&ParsersPythonVisitor::buildModelAndGeomFromUrdf),
-              bp::args("filename (string)", "mesh_dir (string)",
+              static_cast <ModelGeometryHandlerPair_t (*) (const std::string &, const std::vector<std::string> &, bp::object &)> (&ParsersPythonVisitor::buildModelAndGeomFromUrdf),
+              bp::args("filename (string)", "package_dirs (vector of strings)",
                        "Root Joint Model"),
               "Parse the urdf file given in input and return a proper pinocchio model starting with a given root joint and geometry model "
               "(remember to create the corresponding data structures).");
       
       bp::def("buildModelAndGeomFromUrdf",
-              static_cast <ModelGeometryHandlerPair_t (*) (const std::string &, const std::string &)> (&ParsersPythonVisitor::buildModelAndGeomFromUrdf),
-              bp::args("filename (string)", "mesh_dir (string)"),
+              static_cast <ModelGeometryHandlerPair_t (*) (const std::string &, const std::vector<std::string> &)> (&ParsersPythonVisitor::buildModelAndGeomFromUrdf),
+              bp::args("filename (string)", "package_dirs (vector of strings)"),
               "Parse the urdf file given in input and return a proper pinocchio model and geometry model "
               "(remember to create the corresponding data structures).");
       
diff --git a/unittest/geom.cpp b/unittest/geom.cpp
index 03fc2e711..80c00176d 100644
--- a/unittest/geom.cpp
+++ b/unittest/geom.cpp
@@ -205,9 +205,12 @@ BOOST_AUTO_TEST_CASE ( loading_model )
 
 
   std::string filename = PINOCCHIO_SOURCE_DIR"/models/romeo.urdf";
+  std::vector < std::string > package_dirs;
   std::string meshDir  = PINOCCHIO_SOURCE_DIR"/models/";
+  package_dirs.push_back(meshDir);
+
   Model model = se3::urdf::buildModel(filename, se3::JointModelFreeFlyer());
-  GeometryModel geometry_model = se3::urdf::buildGeom(model, filename, meshDir);
+  GeometryModel geometry_model = se3::urdf::buildGeom(model, filename, package_dirs, true);
 
   Data data(model);
   GeometryData geometry_data(data, geometry_model);
@@ -243,16 +246,22 @@ BOOST_AUTO_TEST_CASE ( romeo_joints_meshes_positions )
 
   // Building the model in pinocchio and compute kinematics/geometry for configuration q_pino
   std::string filename = PINOCCHIO_SOURCE_DIR"/models/romeo.urdf";
+  std::vector < std::string > package_dirs;
   std::string meshDir  = PINOCCHIO_SOURCE_DIR"/models/";
-  std::pair < Model, GeometryModel > robot = se3::urdf::buildModelAndGeom(filename, meshDir, se3::JointModelFreeFlyer());
+  package_dirs.push_back(meshDir);
+
+  se3::Model model = se3::urdf::buildModel(filename, se3::JointModelFreeFlyer());
+  se3::GeometryModel geom = se3::urdf::buildGeom(model, filename, package_dirs,  true);
+  std::cout << model << std::endl;
 
-  Data data(robot.first);
-  GeometryData data_geom(data, robot.second);
+
+  Data data(model);
+  GeometryData data_geom(data, geom);
 
   // Configuration to be tested
   
 
-  Eigen::VectorXd q_pino(Eigen::VectorXd::Random(robot.first.nq));
+  Eigen::VectorXd q_pino(Eigen::VectorXd::Random(model.nq));
   q_pino.segment<4>(3) /= q_pino.segment<4>(3).norm();
 
   Eigen::VectorXd q_hpp(q_pino);
@@ -261,9 +270,9 @@ BOOST_AUTO_TEST_CASE ( romeo_joints_meshes_positions )
   q_hpp.segment<4>(3) = quaternion ;
 
 
-  assert(q_pino.size() == robot.first.nq && "wrong config size");
+  assert(q_pino.size() == model.nq && "wrong config size");
 
-  se3::updateGeometryPlacements(robot.first, data, robot.second, data_geom, q_pino);
+  se3::updateGeometryPlacements(model, data, geom, data_geom, q_pino);
 
 
   /// *************  HPP  ************* /// 
@@ -277,7 +286,7 @@ BOOST_AUTO_TEST_CASE ( romeo_joints_meshes_positions )
               "", "");
 
 
-  assert(robot.first.nq == humanoidRobot->configSize () && "Pinocchio model & HPP model config sizes are not the same ");
+  assert(model.nq == humanoidRobot->configSize () && "Pinocchio model & HPP model config sizes are not the same ");
 
   humanoidRobot->currentConfiguration (q_hpp);
   humanoidRobot->computeForwardKinematics ();
@@ -347,16 +356,22 @@ BOOST_AUTO_TEST_CASE ( hrp2_mesh_distance)
 
   // Building the model in pinocchio and compute kinematics/geometry for configuration q_pino
   std::string filename = PINOCCHIO_SOURCE_DIR"/models/romeo.urdf";
+  std::vector < std::string > package_dirs;
   std::string meshDir  = PINOCCHIO_SOURCE_DIR"/models/";
-  std::pair < Model, GeometryModel > robot = se3::urdf::buildModelAndGeom(filename, meshDir, se3::JointModelFreeFlyer());
+  package_dirs.push_back(meshDir);
 
-  Data data(robot.first);
-  GeometryData data_geom(data, robot.second);
+  se3::Model model = se3::urdf::buildModel(filename, se3::JointModelFreeFlyer());
+  se3::GeometryModel geom = se3::urdf::buildGeom(model, filename, package_dirs,  true);
+  std::cout << model << std::endl;
+
+
+  Data data(model);
+  GeometryData data_geom(data, geom);
 
   // Configuration to be tested
   
 
-  Eigen::VectorXd q_pino(Eigen::VectorXd::Random(robot.first.nq));
+  Eigen::VectorXd q_pino(Eigen::VectorXd::Random(model.nq));
   q_pino.segment<4>(3) /= q_pino.segment<4>(3).norm();
 
   Eigen::VectorXd q_hpp(q_pino);
@@ -365,9 +380,9 @@ BOOST_AUTO_TEST_CASE ( hrp2_mesh_distance)
   q_hpp.segment<4>(3) = quaternion ;
 
 
-  assert(q_pino.size() == robot.first.nq && "wrong config size");
+  assert(q_pino.size() == model.nq && "wrong config size");
 
-  se3::updateGeometryPlacements(robot.first, data, robot.second, data_geom, q_pino);
+  se3::updateGeometryPlacements(model, data, geom, data_geom, q_pino);
 
 
   /// *************  HPP  ************* /// 
@@ -381,7 +396,7 @@ BOOST_AUTO_TEST_CASE ( hrp2_mesh_distance)
               "", "");
 
 
-  assert(robot.first.nq == humanoidRobot->configSize () && "Pinocchio model & HPP model config sizes are not the same ");
+  assert(model.nq == humanoidRobot->configSize () && "Pinocchio model & HPP model config sizes are not the same ");
 
   humanoidRobot->currentConfiguration (q_hpp);
   humanoidRobot->computeForwardKinematics ();
@@ -412,8 +427,8 @@ BOOST_AUTO_TEST_CASE ( hrp2_mesh_distance)
 
         std::cout << "comparison between " << body1 << " and " << body2 << std::endl;
 
-        se3::DistanceResult dist_pin = data_geom.computeDistance( robot.second.getGeomId(body1),
-                                                                  robot.second.getGeomId(body2));
+        se3::DistanceResult dist_pin = data_geom.computeDistance( geom.getGeomId(body1),
+                                                                  geom.getGeomId(body2));
 
         Distance_t distance_pin(dist_pin.fcl_distance_result);
         distance_hpp.checkClose(distance_pin);
-- 
GitLab