bindings/python/parsers/python/model.cpp
Go to the documentation of this file.
1 //
2 // Copyright (c) 2016-2020 CNRS INRIA
3 //
4 
5 #include "pinocchio/parsers/python.hpp"
6 
7 #include <iostream>
8 #include <Python.h>
9 #include <boost/shared_ptr.hpp>
10 #include <boost/version.hpp>
11 #include <boost/algorithm/string/predicate.hpp>
12 
13 // Boost 1.58
14 #if BOOST_VERSION / 100 % 1000 == 58
15 #include <fstream>
16 #endif
17 
18 namespace pinocchio
19 {
20  namespace python
21  {
22  namespace bp = boost::python;
23 
24  Model buildModel(const std::string & filename, const std::string & model_name)
25  {
26  Py_Initialize();
27 
28  bp::object main_module = bp::import("__main__");
29  // Get a dict for the global namespace to exec further python code with
30  bp::dict globals = bp::extract<bp::dict>(main_module.attr("__dict__"));
31 
32  // We need to link to the pinocchio PyWrap. We delegate the dynamic loading to the python interpreter.
33  bp::object cpp_module( (bp::handle<>(bp::borrowed(PyImport_AddModule("libpinocchio_pywrap")))) );
34 
35  // That's it, you can exec your python script, starting with a model you
36  // can update as you want.
37  try
38  {
39 // Boost 1.58
40 #if BOOST_VERSION / 100 % 1000 == 58
41  // Avoid a segv with exec_file
42  // See: https://github.com/boostorg/python/pull/15
43  std::ifstream t(filename.c_str());
44  std::stringstream buffer;
45  buffer << t.rdbuf();
46  bp::exec(buffer.str().c_str(), globals);
47 #else // default implementation
48  bp::exec_file((bp::str)filename, globals);
49 #endif
50  }
51  catch (bp::error_already_set & e)
52  {
53  PyErr_PrintEx(0);
54  }
55 
56  Model model;
57  try
58  {
59  bp::object obj_model = globals[model_name];
60  model = bp::extract<Model>(obj_model);
61  }
62  catch (bp::error_already_set & e)
63  {
64  PyErr_PrintEx(0);
65  }
66 
67  // close the interpreter
68  // cf. https://github.com/numpy/numpy/issues/8097
69 #if PY_MAJOR_VERSION < 3
70  Py_Finalize();
71 #else
72 
73  PyObject * poMainModule = PyImport_AddModule("__main__");
74  PyObject * poAttrList = PyObject_Dir(poMainModule);
75  PyObject * poAttrIter = PyObject_GetIter(poAttrList);
76  PyObject * poAttrName;
77 
78  while ((poAttrName = PyIter_Next(poAttrIter)) != NULL)
79  {
80  std::string oAttrName = PyUnicode_AS_DATA(poAttrName);
81 
82  // Make sure we don't delete any private objects.
83  if (!boost::starts_with(oAttrName, "__") || !boost::ends_with(oAttrName, "__"))
84  {
85  PyObject * poAttr = PyObject_GetAttr(poMainModule, poAttrName);
86 
87  // Make sure we don't delete any module objects.
88  if (poAttr && poAttr->ob_type != poMainModule->ob_type)
89  PyObject_SetAttr(poMainModule, poAttrName, NULL);
90  Py_DecRef(poAttr);
91  }
92  Py_DecRef(poAttrName);
93  }
94  Py_DecRef(poAttrIter);
95  Py_DecRef(poAttrList);
96 #endif
97 
98  return model;
99  }
100  } // namespace python
101 } // namespace pinocchio
Model buildModel(const std::string &filename, const std::string &model_name)
Load a model from a Python script.
Main pinocchio namespace.
Definition: timings.cpp:30
JointCollectionTpl & model


pinocchio
Author(s):
autogenerated on Tue Jun 1 2021 02:45:04