bindings/python/parsers/urdf/geometry.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2015-2022 CNRS INRIA
3 //
4 
5 #ifdef PINOCCHIO_WITH_URDFDOM
7 #endif
10 
11 #include <boost/python.hpp>
12 
13 namespace pinocchio
14 {
15  namespace python
16  {
17 
18  namespace bp = boost::python;
19 
20 #ifdef PINOCCHIO_WITH_URDFDOM
21  typedef ::hpp::fcl::MeshLoaderPtr MeshLoaderPtr;
22 
23  void buildGeomFromUrdf_existing(
24  const Model & model,
25  const std::istream & stream,
26  const GeometryType type,
27  GeometryModel & geometry_model,
28  bp::object py_pkg_dirs,
29  bp::object py_mesh_loader)
30  {
31  MeshLoaderPtr mesh_loader = MeshLoaderPtr();
32  if (!py_mesh_loader.is_none())
33  {
34  #ifdef PINOCCHIO_WITH_HPP_FCL
37  mesh_loader = bp::extract<::hpp::fcl::MeshLoaderPtr>(py_mesh_loader);
39  #else
40  PyErr_WarnEx(
41  PyExc_UserWarning, "Mesh loader is ignored because Pinocchio is not built with hpp-fcl",
42  1);
43  #endif
44  }
45 
46  std::vector<std::string> pkg_dirs;
47 
48  bp::extract<std::string> pkg_dir_extract(py_pkg_dirs);
49  bp::extract<bp::list> pkg_dirs_list_extract(py_pkg_dirs);
50  bp::extract<const std::vector<std::string> &> pkg_dirs_vect_extract(py_pkg_dirs);
51  if (py_pkg_dirs.is_none())
52  {
53  } // Provided None
54  else if (pkg_dir_extract.check()) // Provided a string
55  pkg_dirs.push_back(pkg_dir_extract());
56  else if (pkg_dirs_list_extract.check()) // Provided a list of string
57  extract(pkg_dirs_list_extract(), pkg_dirs);
58  else if (pkg_dirs_vect_extract.check()) // Provided a vector of string
59  pkg_dirs = pkg_dirs_vect_extract();
60  else
61  { // Did not understand the provided argument
62  std::string what = bp::extract<std::string>(py_pkg_dirs.attr("__str__")())();
63  throw std::invalid_argument(
64  "pkg_dirs must be either None, a string or a list of strings. Provided " + what);
65  }
66 
67  pinocchio::urdf::buildGeom(model, stream, type, geometry_model, pkg_dirs, mesh_loader);
68  }
69 
70  // This function is complex in order to keep backward compatibility.
71  GeometryModel * buildGeomFromUrdfStream(
72  const Model & model,
73  const std::istream & stream,
74  const GeometryType type,
75  bp::object py_geom_model,
76  bp::object package_dirs,
77  bp::object mesh_loader)
78  {
79  GeometryModel * geom_model;
80  if (py_geom_model.is_none())
81  geom_model = new GeometryModel;
82  else
83  {
84  bp::extract<GeometryModel *> geom_model_extract(py_geom_model);
85  if (geom_model_extract.check())
86  geom_model = geom_model_extract();
87  else
88  {
89  // When backward compat is removed, the code in this `else` section
90  // can be removed and the argument py_geom_model changed into a GeometryModel*
91  PyErr_WarnEx(
92  PyExc_UserWarning,
93  "You passed package dir(s) via argument geometry_model and provided package_dirs.", 1);
94 
95  // At this stage, py_geom_model contains the package dir(s). mesh_loader can
96  // be passed either by package_dirs or mesh_loader
97  bp::object new_pkg_dirs = py_geom_model;
98  if (!package_dirs.is_none() && !mesh_loader.is_none())
99  throw std::invalid_argument(
100  "package_dirs and mesh_loader cannot be both provided since you passed the package "
101  "dirs via argument geometry_model.");
102  if (mesh_loader.is_none())
103  mesh_loader = package_dirs;
104  try
105  {
106  // If geom_model is not a valid package_dir(s), then rethrow with clearer message
107  geom_model = new GeometryModel;
108  buildGeomFromUrdf_existing(model, stream, type, *geom_model, new_pkg_dirs, mesh_loader);
109  return geom_model;
110  }
111  catch (std::invalid_argument const & e)
112  {
113  std::cout << "Caught: " << e.what() << std::endl;
114  throw std::invalid_argument("Argument geometry_model should be a GeometryModel");
115  }
116  }
117  }
118  buildGeomFromUrdf_existing(model, stream, type, *geom_model, package_dirs, mesh_loader);
119  return geom_model;
120  }
121 
122  GeometryModel * buildGeomFromUrdfFile(
123  const Model & model,
124  const std::string & filename,
125  const GeometryType type,
126  bp::object geom_model,
127  bp::object package_dirs,
128  bp::object mesh_loader)
129  {
130  std::ifstream stream(filename.c_str());
131  if (!stream.is_open())
132  {
133  throw std::invalid_argument(filename + " does not seem to be a valid file.");
134  }
135  return buildGeomFromUrdfStream(model, stream, type, geom_model, package_dirs, mesh_loader);
136  }
137 
138  GeometryModel * buildGeomFromUrdfString(
139  const Model & model,
140  const std::string & xmlString,
141  const GeometryType type,
142  bp::object geom_model,
143  bp::object package_dirs,
144  bp::object mesh_loader)
145  {
146  std::istringstream stream(xmlString);
147  return buildGeomFromUrdfStream(model, stream, type, geom_model, package_dirs, mesh_loader);
148  }
149 
150  #ifdef PINOCCHIO_WITH_HPP_FCL
151  #define MESH_LOADER_DOC \
152  "\tmesh_loader: an hpp-fcl mesh loader (to load only once the related geometries).\n"
153  #else // #ifdef PINOCCHIO_WITH_HPP_FCL
154  #define MESH_LOADER_DOC "\tmesh_loader: unused because the Pinocchio is built without hpp-fcl\n"
155  #endif // #ifdef PINOCCHIO_WITH_HPP_FCL
156  template<std::size_t owner_arg = 1>
157  struct return_value_policy : bp::return_internal_reference<owner_arg>
158  {
159  public:
160  template<class ArgumentPackage>
161  static PyObject * postcall(ArgumentPackage const & args_, PyObject * result)
162  {
163  // If owner_arg exists, we run bp::return_internal_reference postcall
164  // result lifetime will be tied to the owner_arg lifetime
165  PyObject * patient = bp::detail::get_prev<owner_arg>::execute(args_, result);
166  if (patient != Py_None)
167  return bp::return_internal_reference<owner_arg>::postcall(args_, result);
168  // If owner_arg doesn't exist, then Python will have to manage the result lifetime
169  bp::extract<GeometryModel *> geom_model_extract(result);
170  if (geom_model_extract.check())
171  {
172  return bp::to_python_indirect<GeometryModel, bp::detail::make_owning_holder>()(
173  geom_model_extract());
174  }
175  // If returned value is not a GeometryModel*, then raise an error
176  PyErr_SetString(
177  PyExc_RuntimeError,
178  "pinocchio::python::return_value_policy only works on GeometryModel* data type");
179  return 0;
180  }
181  };
182 
183  template<typename F>
184  void defBuildUrdf(const char * name, F f, const char * urdf_arg, const char * urdf_doc)
185  {
186  std::ostringstream doc;
187  doc << "Parse the URDF file given as input looking for the geometry of the given input model "
188  "and\n"
189  "and store either the collision geometries (GeometryType.COLLISION) or the visual "
190  "geometries (GeometryType.VISUAL) in a GeometryModel object.\n"
191  "Parameters:\n"
192  "\tmodel: model of the robot\n"
193  "\n"
194  << urdf_arg << ": " << urdf_doc
195  << "\n"
196  "\tgeom_type: type of geometry to extract from the URDF file (either the VISUAL for "
197  "display or the COLLISION for collision detection).\n"
198  "\tgeometry_model: if provided, this geometry model will be used to store the parsed "
199  "information instead of creating a new one\n"
200  "\tpackage_dirs: either a single path or a vector of paths pointing to folders "
201  "containing the model of the robot\n" MESH_LOADER_DOC "\n"
202  "Retuns:\n"
203  "\ta new GeometryModel if `geometry_model` is None else `geometry_model` (that has "
204  "been updated).\n";
205 
206  bp::def(
207  name, f,
208  (bp::arg("model"), bp::arg(urdf_arg), bp::arg("geom_type"),
209  bp::arg("geometry_model") = static_cast<GeometryModel *>(NULL),
210  bp::arg("package_dirs") = bp::object(), bp::arg("mesh_loader") = bp::object()),
211  doc.str().c_str(), return_value_policy<4>());
212  }
213 
214 #endif
215 
217  {
218 #ifdef PINOCCHIO_WITH_URDFDOM
219  defBuildUrdf(
220  "buildGeomFromUrdf", buildGeomFromUrdfFile, "urdf_filename",
221  "path to the URDF file containing the model of the robot");
222  defBuildUrdf(
223  "buildGeomFromUrdfString", buildGeomFromUrdfString, "urdf_string",
224  "a string containing the URDF model of the robot");
225 #endif // #ifdef PINOCCHIO_WITH_URDFDOM
226  }
227  } // namespace python
228 } // namespace pinocchio
boost::python
pinocchio::name
std::string name(const LieGroupGenericTpl< LieGroupCollection > &lg)
Visit a LieGroupVariant to get the name of it.
PINOCCHIO_COMPILER_DIAGNOSTIC_POP
#define PINOCCHIO_COMPILER_DIAGNOSTIC_POP
Definition: include/pinocchio/macros.hpp:125
autodiff-rnea.f
f
Definition: autodiff-rnea.py:24
PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED
#define PINOCCHIO_COMPILER_DIAGNOSTIC_IGNORED_MAYBE_UNINITIALIZED
Definition: include/pinocchio/macros.hpp:129
simulation-pendulum.type
type
Definition: simulation-pendulum.py:18
list.hpp
append-urdf-model-with-another-model.package_dirs
package_dirs
Definition: append-urdf-model-with-another-model.py:20
filename
filename
python
urdf.hpp
pinocchio::urdf::buildGeom
GeometryModel & buildGeom(const ModelTpl< Scalar, Options, JointCollectionTpl > &model, const std::string &filename, const GeometryType type, GeometryModel &geom_model, const std::vector< std::string > &package_paths=std::vector< std::string >(), ::hpp::fcl::MeshLoaderPtr mesh_loader=::hpp::fcl::MeshLoaderPtr())
Build The GeometryModel from a URDF file. Search for meshes in the directories specified by the user ...
PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
#define PINOCCHIO_COMPILER_DIAGNOSTIC_PUSH
macros for pragma push/pop/ignore deprecated warnings
Definition: include/pinocchio/macros.hpp:124
append-urdf-model-with-another-model.geom_model
geom_model
Definition: append-urdf-model-with-another-model.py:26
pinocchio::python::extract
void extract(const boost::python::list &list, std::vector< T, Allocator > &vec)
Definition: list.hpp:24
pinocchio::GeometryType
GeometryType
Definition: multibody/geometry-object.hpp:24
pinocchio::python::exposeURDFGeometry
void exposeURDFGeometry()
Definition: bindings/python/parsers/urdf/geometry.cpp:216
urdf.hpp
pinocchio::Model
ModelTpl< context::Scalar, context::Options > Model
Definition: multibody/fwd.hpp:33
pinocchio::model
JointCollectionTpl & model
Definition: joint-configuration.hpp:1116
pinocchio
Main pinocchio namespace.
Definition: timings.cpp:27


pinocchio
Author(s):
autogenerated on Sat Jun 1 2024 02:40:35